package org.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.example.entity.WorkingCalendar;
import org.example.models.R;
import org.example.service.WorkingCalendarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @Author: 鸢一折纸
 * @Email: 3498881048@qq.com
 * @Date: 2025/08/07 9:23
 * @Description: 工作日历控制器，处理节假日同步和查询
 **/

@RestController
@RequestMapping("/workingCalendar")
public class WorkingCalendarController {

    @Autowired
    private WorkingCalendarService workingCalendarService;

    @Autowired
    private RestTemplate restTemplate;

    private static final String API_KEY = "2025";
    // 按照指定格式使用API地址
    private static final String HOLIDAY_API_URL = "https://api.jiejiariapi.com/v1/holidays/" + API_KEY;

    @GetMapping("/page")
    public R<Page<WorkingCalendar>> getAllHolidayType(
            @RequestParam(name = "current", defaultValue = "1") int current,
            @RequestParam(name = "size", defaultValue = "4") int size,
            @RequestParam(name = "dateTime", required = false) String dateTime,
            @RequestParam(name = "startDate", required = false) String startDate,
            @RequestParam(name = "endDate", required = false) String endDate
    ){
        QueryWrapper<WorkingCalendar> query = new QueryWrapper<>();
        if (dateTime != null && !dateTime.isEmpty()) {
            query.lambda().like(WorkingCalendar::getDateTime, dateTime);
        }
        if (startDate != null && !startDate.isEmpty() && endDate != null && !endDate.isEmpty()) {
            query.lambda().between(WorkingCalendar::getDateTime, startDate, endDate);
        }

        query.lambda().orderByDesc(WorkingCalendar::getDateTime);

        Page<WorkingCalendar> page = new Page<>(current, size);
        workingCalendarService.page(page, query);
        return R.success(page);
    }

    @GetMapping("/AllList")
    public R<List<WorkingCalendar>> getAllList(){
        return R.success(workingCalendarService.list());
    }

    @PostMapping("/insert")
    public R insertAttendanceCycle(@RequestBody WorkingCalendar workingCalendar){
        QueryWrapper<WorkingCalendar> query = new QueryWrapper<>();
        query.lambda().eq(WorkingCalendar::getDateTime, workingCalendar.getDateTime());

        if (workingCalendarService.getOne(query) != null) {
            return R.error("该日期已存在");
        }

        return workingCalendarService.save(workingCalendar) ? R.success("添加成功") : R.error("添加失败");
    }

    @PostMapping("/update")
    public R updateAttendanceCycle(@RequestBody WorkingCalendar workingCalendar){
        return workingCalendarService.updateById(workingCalendar) ? R.success("修改成功") : R.error("修改失败");
    }

    /**
     * 每月25号0点同步下月节假日
     */
    @Scheduled(cron = "0 0 0 25 * ?")
    public void autoSyncNextMonthHolidays() {
        LocalDate today = LocalDate.now();
        LocalDate nextMonth = today.plusMonths(1);
        syncHolidayData(nextMonth.getYear(), nextMonth.getMonthValue());
    }

    /**
     * 同步指定年月的节假日数据
     */
    private void syncHolidayData(int year, int month) {
        try {
            String apiUrl = HOLIDAY_API_URL;
            JSONObject response = restTemplate.getForObject(apiUrl, JSONObject.class);

            // 验证API响应是否为空
            if (response == null) {
                throw new RuntimeException("API返回空响应");
            }

            // API返回直接以日期为键的JSON对象，直接处理
            Set<String> dateKeys = response.keySet();
            // 日期格式化器匹配API返回的"yyyy-MM-dd"格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            for (String dateKey : dateKeys) {
                // 解析日期并处理格式异常
                LocalDate date;
                try {
                    date = LocalDate.parse(dateKey, formatter);
                } catch (DateTimeParseException e) {
                    continue; // 跳过格式不正确的日期
                }

                // 只处理目标年月的数据
                if (date.getYear() != year || date.getMonthValue() != month) {
                    continue;
                }

                JSONObject dayInfo = response.getJSONObject(dateKey);
                saveHolidayToDB(date, dayInfo);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存节假日数据到数据库
     */
    private void saveHolidayToDB(LocalDate date, JSONObject dayInfo) {
        // 查询是否已有该日期记录
        LambdaQueryWrapper<WorkingCalendar> query = new LambdaQueryWrapper<>();
        query.eq(WorkingCalendar::getDateTime, java.sql.Date.valueOf(date));
        WorkingCalendar calendar = workingCalendarService.getOne(query);

        // 不存在则创建新记录
        if (calendar == null) {
            calendar = new WorkingCalendar();
            calendar.setSubmitAt(new Date());
        }

        // 更新核心字段，匹配API返回的实际字段
        calendar.setDateTime(java.sql.Date.valueOf(date));
        calendar.setWeek(getWeekName(date.getDayOfWeek().getValue() % 7)); // 转换周日为0
        calendar.setWorkingCondition(dayInfo.getBoolean("isOffDay") ? "节假日" : "节假日调休");
        calendar.setFestival(dayInfo.getString("name"));
        calendar.setCompensationProvisions(dayInfo.getString("compensation") != null ?
                dayInfo.getString("compensation") : "");
        calendar.setUpdatedAt(new Date());

        workingCalendarService.saveOrUpdate(calendar);
    }

    private String getWeekName(int weekValue) {
        switch (weekValue) {
            case 0:
                return "星期日";
            case 1:
                return "星期一";
            case 2:
                return "星期二";
            case 3:
                return "星期三";
            case 4:
                return "星期四";
            case 5:
                return "星期五";
            case 6:
                return "星期六";
            default:
                return "未知";
        }
    }

    /**
     * 手动触发同步接口
     */
    @GetMapping("/manualSync")
    public R manualSync(@RequestParam int year, @RequestParam int month) {
        try {
            syncHolidayData(year, month);
            return R.success("同步成功");
        } catch (Exception e) {
            return R.error("同步失败: " + e.getMessage());
        }
    }
}
